﻿using NovoDataBase;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml.Linq;

namespace NovoSerDes
{
    public partial class Form_RegDump : Form
    {
        SerDesComm commDev;
        public Form_RegDump(SerDesComm _commDev)
        {
            InitializeComponent();
            this.commDev = _commDev;
            this.cmb_IICMode.SelectedIndex = 3;
        }

        private IICMode IICModeDecode(string msg)
        {
            IICMode i2cMode = IICMode.A16D32;
            if (Enum.TryParse(msg.ToUpper(), true, out i2cMode))
                return i2cMode;
            else
                return IICMode.None;
        }

        private List<string[]> ReadRegister(byte devAddr, UInt16 startRegAddr, UInt16 readCount, bool ifIncrease, IICMode i2cMode)
        {
            if(commDev == null) 
                return null;

            List<string[]> regList = new List<string[]> { };

            object regData = 0;
            UInt16 tempRegAddr = 0;
            int byteCnt_RegAddr = ((byte)i2cMode >> 4) & 0x0F;
            int byteCnt_RegData = ((byte)i2cMode & 0x0F);
            for (uint ix = 0; ix < readCount; ix++) 
            {
                if(ifIncrease)
                    tempRegAddr = (UInt16)(startRegAddr + (ix * byteCnt_RegData));
                else
                    tempRegAddr = (UInt16)(startRegAddr - (ix * byteCnt_RegData));

                if (!commDev.IICRead(devAddr, tempRegAddr, out regData, i2cMode))
                {
                    MessageBox.Show(String.Format("Read Reg:0x{0} failed!", ix.ToString("X4")));
                    break;
                }
                regList.Add(new string[] { 
                    "0x" + (tempRegAddr).ToString(String.Format("X{0}", 2 * byteCnt_RegAddr)),  
                    "0x" + Convert.ToUInt32(regData).ToString(String.Format("X{0}", 2 * byteCnt_RegData))
                    });

                this.lbl_Progress.Text = ((double)(ix+1)/(double)(readCount) *100).ToString("F1") + "%";
                this.Refresh();
            }            

            return regList;
        }


        private void btn_SaveTo_Click(object sender, EventArgs e)
        {
            StreamWriter sw = null;
            try
            {
                this.Cursor = Cursors.WaitCursor;

                SaveFileDialog savefiledlg = new SaveFileDialog();
                savefiledlg.Title = "Dump to...";
                savefiledlg.Filter = "CSV file(*.csv)|*.csv|Text file(*.txt)|*.txt";
                savefiledlg.RestoreDirectory = true;
                string filename = "";
                if (savefiledlg.ShowDialog() == DialogResult.OK)
                {
                    filename = savefiledlg.FileName;
                }
                else
                    return;

                byte devAddr = (byte)(this.numUD_ChipAddr.Value * 2);
                UInt16 startRegAddr = (UInt16)(this.numUD_StartRegAddr.Value);
                UInt16 endRegAddr = (UInt16)(this.numUP_EndRegAddr.Value);

                UInt16 readCount = 0;// (UInt16)(this.numUD_RegCount.Value);
                bool ifIncrease = (startRegAddr <= endRegAddr) ? true : false;
                if (startRegAddr <= endRegAddr)
                    readCount = Convert.ToUInt16((endRegAddr - startRegAddr) / 4 + 1);
                else
                    readCount = Convert.ToUInt16((startRegAddr - endRegAddr) / 4 + 1);

                IICMode i2cMode = IICModeDecode(this.cmb_IICMode.SelectedItem.ToString());

                // Read RegData
                List<string[]> result = ReadRegister(devAddr, startRegAddr, readCount, ifIncrease, i2cMode);

                // write file
                sw = File.CreateText(filename);

                bool ifCSV = Path.GetExtension(filename).Contains("csv");

                // write header
                if (ifCSV)
                    sw.WriteLine(string.Join(",", new string[]{"RegAddr(Hex)", "RegData(Hex)"}));
                else
                    sw.WriteLine(string.Join(" = ", new string[] { "RegAddr(Hex)", "RegData(Hex)" }));

                for (int ix = 0; ix < result.Count; ix++)
                {
                    if(ifCSV)
                        sw.WriteLine(string.Join(",", result[ix]));
                    else
                        sw.WriteLine(string.Join(" = ", result[ix]));
                }                
            }
            catch (Exception ex)
            {
                MessageBox.Show("Save script file failed! Error:{0}", ex.Message);
            }
            finally
            {
                if(sw != null)
                    sw.Close();
                this.Cursor = Cursors.Default;
            }
        }

        private void numUD_StartRegAddr_ValueChanged(object sender, EventArgs e)
        {
            IICMode i2cMode = IICModeDecode(this.cmb_IICMode.SelectedItem.ToString());
            int byteCnt_RegData = ((byte)i2cMode & 0x0F);

            this.numUD_RegCount.Maximum = (UInt16.MaxValue + 1 - this.numUD_StartRegAddr.Value)/ byteCnt_RegData;
        }

        private void Form_RegDump_Load(object sender, EventArgs e)
        {

        }
    }
}
